#pragma once
#ifdef OBLIVION
class BSStringT;
class EffectItem;
class EnchantmentItem;
class TESBoundObject;
class TESObjectARMO;
class TESObjectCLOT;
class TESObjectWEAP;
class TESActorBase;
class TESObjectREFR;
class ContainerExtraData;
class EffectItemGenerator;
class MagicItemGenerator;
class AffixFilter;
struct Affix;
struct AffixList;

#include "API/Magic/Magic.h"
#include <vector>
#include <utility>

struct Generation {
	static std::vector<std::pair<UInt32, UInt32> >	generatedItems;

	static bool				CheckObject(const TESBoundObject* base);
	
	template<typename T>
	static bool				GetAffixList(const T* base, std::vector<AffixFilter*>*& filters, AffixList& prefixes, AffixList& suffixes, UInt16 level, bool LtEq = true);
	static bool				GetAffixList(const TESBoundObject* base, std::vector<AffixFilter*>*& filters, AffixList& prefixes, AffixList& suffixes, UInt16 level, bool LtEq = true);
	static inline bool		GetAffixList(const TESObjectARMO* base, std::vector<AffixFilter*>*& filters, AffixList& prefixes, AffixList& suffixes, UInt16 level, bool LtEq = true);
	static inline bool		GetAffixList(const TESObjectCLOT* base, std::vector<AffixFilter*>*& filters, AffixList& prefixes, AffixList& suffixes, UInt16 level, bool LtEq = true);
	static inline bool		GetAffixList(const TESObjectWEAP* base, std::vector<AffixFilter*>*& filters, AffixList& prefixes, AffixList& suffixes, UInt16 level, bool LtEq = true);

	static UInt16			AddAffixTo(std::vector<EffectItem*>& geis, EnchantmentItem* ench, BSStringT& name, const Affix* affix, Magic::RangeTypes range, bool isRare = false, UInt8 chrgB = 0);
	static UInt16			GenerateSlot(std::vector<EffectItem*>& geis, EnchantmentItem* ench, BSStringT& name, const AffixList& prefixes, const AffixList& suffixes, Magic::RangeTypes range, bool& isRare);
	static void				NameRareItem(BSStringT& name, const std::vector<AffixFilter*>& flts);
	static void				ApplyEffectsTo(EnchantmentItem* ench, std::vector<EffectItem*>& geis);
	
	template<typename T>
	static T*				Enchant(const T* base, UInt16 level, bool LtEq = true, std::vector<AffixFilter*>* flts = NULL);
	static TESBoundObject*	Enchant(const TESBoundObject* base, UInt16 level, bool LtEq = true, std::vector<AffixFilter*>* flts = NULL);
	static inline TESObjectARMO*	Enchant(const TESObjectARMO* base, UInt16 level, bool LtEq = true, std::vector<AffixFilter*>* flts = NULL);
	static inline TESObjectCLOT*	Enchant(const TESObjectCLOT* base, UInt16 level, bool LtEq = true, std::vector<AffixFilter*>* flts = NULL);
	static inline TESObjectWEAP*	Enchant(const TESObjectWEAP* base, UInt16 level, bool LtEq = true, std::vector<AffixFilter*>* flts = NULL);

	static TESActorBase*	player;
	static TESObjectREFR*	playerRef;
	static void				ProcessContainer(ContainerExtraData* extraData, UInt32 level);
};
#endif
